package coder.nav.schedule.action;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import coder.nav.enums.NavCashFlagEnums;
import coder.nav.enums.NavCashTypeEnums;
import coder.nav.model.bo.NavCashQueryBO;
import coder.nav.model.bo.NavTaskActionBO;
import coder.nav.model.vo.NavCashVO;
import coder.nav.service.NavCashService;
import coder.nav.utils.MsnUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.*;

@Slf4j
@Component
public class NavTaskDayCashAction extends NavTaskNoticeAction {

    @Autowired
    private NavCashService cashService;

    @Override
    public String title() {
        return "记账日报";
    }

    @Override
    public String context() {
        return "";
    }

    @Override
    public String params() {
        return super.params();
    }

    @Override
    public Date executeTime() {
        return DateUtils.addMinutes(DateUtils.addHours(DateUtil.beginOfDay(new Date()), 9), 0);
    }

    @Override
    public NavTaskActionBO getEntity(Long userId) {
        NavTaskActionBO bo = super.getEntity(userId);
        bo.setNeedToHtml(false);
        return bo;
    }

    @Override
    public void addTask(Long userId) {
        NavTaskActionBO task = this.getEntity(userId);
        boolean isWork = MsnUtils.isWork(task.getActionTime());
        if(!isWork) {
            // 非工作日推迟三小时发送
            task.setActionTime(DateUtils.addHours(task.getActionTime(), 3));
        }
        Date date = DateUtils.addDays(task.getActionTime(), -1);
        Integer year = DateUtil.year(date);
        Integer month = DateUtil.month(date) + 1;
        Integer day = DateUtil.dayOfMonth(date);
        String week = DateUtil.dayOfWeekEnum(date).toChinese("周");

        NavCashQueryBO monthBO = new NavCashQueryBO();
        monthBO.setYear(year);
        monthBO.setMonth(month);

        NavCashQueryBO dayBO = BeanUtil.copyProperties(monthBO, NavCashQueryBO.class);
        dayBO.setDay(day);

        // 昨日支出
        NavCashQueryBO daySubBO = BeanUtil.copyProperties(dayBO, NavCashQueryBO.class);
        daySubBO.setFlags(Collections.singletonList(NavCashFlagEnums.SUB.getKey()));
        BigDecimal daySubCash = cashService.getSum(daySubBO, task.getUserId());

        // 昨日收入
        NavCashQueryBO dayAddBO = BeanUtil.copyProperties(dayBO, NavCashQueryBO.class);
        dayAddBO.setFlags(Collections.singletonList(NavCashFlagEnums.ADD.getKey()));
        BigDecimal dayAddCash = cashService.getSum(dayAddBO, task.getUserId());

        // 本月支出
        NavCashQueryBO monthSubBO = BeanUtil.copyProperties(monthBO, NavCashQueryBO.class);
        monthSubBO.setFlags(Collections.singletonList(NavCashFlagEnums.SUB.getKey()));
        BigDecimal monthSubCash = cashService.getSum(monthSubBO, task.getUserId());

        // 本月收入
        NavCashQueryBO monthAddBO = BeanUtil.copyProperties(monthBO, NavCashQueryBO.class);
        monthAddBO.setFlags(Collections.singletonList(NavCashFlagEnums.ADD.getKey()));
        BigDecimal monthAddCash = cashService.getSum(monthAddBO, task.getUserId());

        // 日均支出
        NavCashQueryBO avgSubBO = BeanUtil.copyProperties(monthBO, NavCashQueryBO.class);
        avgSubBO.setStartDate(DateUtil.parse(year + "-" + month +  "-01"));
        avgSubBO.setEndDate(date);
        BigDecimal aveSubCash = cashService.getAvg(avgSubBO, userId);

        // 日均(饮食)
        NavCashQueryBO avgFoodSubBO = BeanUtil.copyProperties(avgSubBO, NavCashQueryBO.class);
        avgFoodSubBO.setTypes(Collections.singletonList(NavCashTypeEnums.FOOD.getKey()));
        BigDecimal avgFoodSubCash = cashService.getAvg(avgFoodSubBO, userId);

        // 收支明细
        List<NavCashVO> list = cashService.getCashList(dayBO, userId);
        StringBuilder detailCash = new StringBuilder();
        if(CollectionUtils.isNotEmpty(list)) {
            for(NavCashVO cash : list) {
                String flag = Objects.equals(cash.getFlag(), 1) ? "income" : "expense";
                String icon = NavCashTypeEnums.getIconByKey(cash.getType());
                String temp = "\n"
                        + "\n\t\t\t<li class='transaction-item'>"
                        + "\n\t\t\t    <div class='transaction-info'>"
                        + "\n\t\t\t        <div class='transaction-icon'>" + icon + "</div>"
                        + "\n\t\t\t        <div class='transaction-details'>"
                        + "\n\t\t\t            <div class='transaction-name'>%s</div>"
                        + "\n\t\t\t            <div class='transaction-category'>%s</div>"
                        + "\n\t\t\t        </div>"
                        + "\n\t\t\t    </div>"
                        + "\n\t\t\t    <div class='transaction-amount " + flag + "'>￥%s</div>"
                        + "\n\t\t\t</li>";
                String context = cash.getTitle();
                if(StringUtils.isNotBlank(cash.getRemark())) {
                    context += "：" + cash.getRemark();
                }
                detailCash.append(String.format(temp, context, cash.getChannelDesc(), cash.getMoney()));
            }
            detailCash.append("\n");
        }

        // 记账日期
        String dayCashDate = String.format("%s月%s日(%s)", month, day, week);
        task.setTitle(task.getTitle() + dayCashDate);

        // 记账日期、昨日收入、昨日支出、本月收入、本月支出、本月日均支出、日均饮食支出、收支明细
        String template = getTemp().replaceAll("%", "%%").replaceAll("%%s", "%s");
        String context = String.format(template, dayCashDate, monthAddCash, monthSubCash, dayAddCash, daySubCash, aveSubCash, avgFoodSubCash, detailCash);
        context = context.replaceAll("%%", "%");
        task.setContext(context);

        super.taskService.saveTaskAction(task);
    }

    @Override
    public void actionTask(NavTaskActionBO task) {
        super.actionTask(task);
    }

    private static String getTemp() {
        ClassLoader classLoader = NavTaskDayCashAction.class.getClassLoader();
        InputStream is = classLoader.getResourceAsStream("static/temp/daycash.html");
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();
        String line = null;
        while(true) {
            try {
                if ((line = br.readLine()) == null) break;
            } catch (IOException ignored) {}
            sb.append(line).append("\n");
        }
        return sb.toString();
    }

}
